package black.market.location;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import black.market.main.BlackPublic;

public class MapContentProvider extends ContentProvider {
	private static final String LOGTAG = "MapContentProvider";

	public static final int DBVER = 1;
	public static final String DATABASE_NAME = "example_map.db";
	public static final String MAP_ADDRESS_ID = "map_address_id"; // 테이블 유니크 SEQ
																	// ID
	public static final String MAP_GEOPOINT_ID = "map_geopoint_id"; // 테이블 유니크
																	// SEQ ID
	public static final String MAP_ADDRESS_TABLE = "map_address_table"; // 테이블
																		// 이름
	public static final String MAP_GEOPOINT_TABLE = "map_geopoint_table";
	public static final String MAP_LOCALCODE = "map_localcode"; // 지역코드
	public static final String MAP_LOCALNAME = "map_localname"; // 지역명
	public static final String MAP_FULLNAME = "map_fullname"; // 전체 주소
	public static final String MAP_NAME1 = "map_name1"; // 지역명1(광역시 이상, 도)
	public static final String MAP_NAME2 = "map_name2"; // 지역명2(시/ 군)
	public static final String MAP_NAME3 = "map_name3"; // 지역명3(동/읍/면)
	public static final String MAP_LAT = "map_latitude"; // 지역명3(동/읍/면)
	public static final String MAP_LNG = "map_longitude"; // 지역명3(동/읍/면)
	public static final String MAP_DATATYPE = "map_datatype"; // 지도 정보 제공처

	private static final int ADDRESS_ALLCURSOR = 1;
	private static final int ADDRESS_ONECURSOR = 2;
	private static final int GEOPOINT_ALLCURSOR = 3;
	private static final int GEOPOINT_ONECURSOR = 4;

	private SQLiteDatabase database = null;

	public static final Uri MAP_ADDRESS_URI = Uri.parse("content://black.market.location.MapContentProvider/addr");
	public static final Uri MAP_GEOPOINT_URI = Uri.parse("content://black.market.location.MapContentProvider/geo");
	static final UriMatcher MATCHER;
	static {
		MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
		MATCHER.addURI("black.market.location.MapContentProvider", "addr", ADDRESS_ALLCURSOR);
		MATCHER.addURI("black.market.location.MapContentProvider", "addr/*", ADDRESS_ONECURSOR);
		MATCHER.addURI("black.market.location.MapContentProvider", "geo", GEOPOINT_ALLCURSOR);
		MATCHER.addURI("black.market.location.MapContentProvider", "geo/*", GEOPOINT_ONECURSOR);
	}

	private static final String MAP_ADDRESS_CREATE = "CREATE TABLE " + MAP_ADDRESS_TABLE + " (" + MAP_ADDRESS_ID
			+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + MAP_LOCALCODE + " STRING," + MAP_LOCALNAME + " STRING," + MAP_FULLNAME + " STRING,"
			+ MAP_NAME1 + " STRING," + MAP_NAME2 + " STRING," + MAP_NAME3 + " STRING" + MAP_DATATYPE + " STRING" + ");";

	private static final String MAP_GEOPOINT_CREATE = "CREATE TABLE " + MAP_GEOPOINT_TABLE + " (" + MAP_GEOPOINT_ID
			+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + MAP_LAT + " STRING, " + MAP_LNG + " STRING" + ");";

	@Override
	public boolean onCreate() {
		// TODO Auto-generated method stub
		MapDBHelper dbHelper = new MapDBHelper(getContext(), DATABASE_NAME, null, DBVER);
		database = dbHelper.getWritableDatabase();
		return (database == null) ? false : true;
	}

	@Override
	public String getType(Uri uri) {
		// TODO Auto-generated method stub
		switch (MATCHER.match(uri)) {
		case ADDRESS_ALLCURSOR:
			return "vnd.black.market.location.MapContentProvider.dir//addr";
		case ADDRESS_ONECURSOR:
			return "vnd.black.market.location.MapContentProvider.item//addr";
		case GEOPOINT_ALLCURSOR:
			return "vnd.black.market.location.MapContentProvider.dir//geo";
		case GEOPOINT_ONECURSOR:
			return "vnd.black.market.location.MapContentProvider.item//geo";
		default:
			throw new IllegalArgumentException(LOGTAG + " Unsupport URI: " + uri);
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		// TODO Auto-generated method stub
		Uri tmpUri = null;
		switch (MATCHER.match(uri)) {
		case ADDRESS_ALLCURSOR:
			long addrId = database.insert(MAP_ADDRESS_TABLE, "", values);
			BlackPublic.debugLog(LOGTAG, "Insert Count: " + addrId);
			if (addrId > 0) {
				tmpUri = ContentUris.withAppendedId(MAP_ADDRESS_URI, addrId);
				getContext().getContentResolver().notifyChange(tmpUri, null);
			} else {
				try {
					throw new SQLException("Fail to add new item into " + uri);
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			break;
		case GEOPOINT_ALLCURSOR:
			long geoId = database.insert(MAP_GEOPOINT_TABLE, "", values);
			BlackPublic.debugLog(LOGTAG, "Insert Count: " + geoId);
			if (geoId > 0) {
				tmpUri = ContentUris.withAppendedId(MAP_GEOPOINT_URI, geoId);
				getContext().getContentResolver().notifyChange(tmpUri, null);
			} else {
				try {
					throw new SQLException("Fail to add new item into " + uri);
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			break;

		default:
			try {
				throw new IllegalAccessException("Unsupport URI: " + uri);
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			break;
		}
		return tmpUri;
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		// TODO Auto-generated method stub
		int count = 0;
		switch (MATCHER.match(uri)) {
		case ADDRESS_ALLCURSOR:
			count = database.delete(MAP_ADDRESS_TABLE, selection, selectionArgs);
			break;
		case ADDRESS_ONECURSOR:
			count = database.delete(MAP_ADDRESS_TABLE, selection, selectionArgs);
			break;
		case GEOPOINT_ALLCURSOR:
			count = database.delete(MAP_GEOPOINT_TABLE, selection, selectionArgs);
			break;
		case GEOPOINT_ONECURSOR:
			count = database.delete(MAP_GEOPOINT_TABLE, selection, selectionArgs);
			break;

		default:
			throw new IllegalArgumentException("Unsupport URI:" + uri);
		}
		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
		// TODO Auto-generated method stub
		int count = 0;
		switch (MATCHER.match(uri)) {
		case ADDRESS_ALLCURSOR:
			count = database.update(MAP_ADDRESS_TABLE, values, selection, selectionArgs);
			break;
		case ADDRESS_ONECURSOR:
			count = database.update(MAP_ADDRESS_TABLE, values, selection, selectionArgs);
			break;
		case GEOPOINT_ALLCURSOR:
			count = database.update(MAP_GEOPOINT_TABLE, values, selection, selectionArgs);
			break;
		case GEOPOINT_ONECURSOR:
			count = database.update(MAP_GEOPOINT_TABLE, values, selection, selectionArgs);
			break;

		default:
			try {
				throw new IllegalAccessException("Unsupport URI: " + uri);
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			break;
		}
		return count;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
		// TODO Auto-generated method stub
		SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
		switch (MATCHER.match(uri)) {
		case ADDRESS_ALLCURSOR:
			builder.setTables(MAP_ADDRESS_TABLE);
			break;
		case ADDRESS_ONECURSOR:
			builder.setTables(MAP_ADDRESS_TABLE);
			break;
		case GEOPOINT_ALLCURSOR:
			builder.setTables(MAP_GEOPOINT_TABLE);
			break;
		case GEOPOINT_ONECURSOR:
			builder.setTables(MAP_GEOPOINT_TABLE);
			break;
		default:
			try {
				throw new IllegalAccessException("Unsupport URI: " + uri);
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			break;
		}
		Cursor cursor = builder.query(database, projection, selection, selectionArgs, null, null, sortOrder);
		cursor.setNotificationUri(getContext().getContentResolver(), uri);
		return cursor;
	}

	public static class MapDBHelper extends SQLiteOpenHelper {
		private static final String LOGTAG = "MapDBHelper";

		public MapDBHelper(Context context, String name, CursorFactory factory, int version) {
			super(context, name, factory, version);
			// TODO Auto-generated constructor stub
		}

		@Override
		public void onCreate(SQLiteDatabase db) {
			// TODO Auto-generated method stub
			BlackPublic.debugLog(LOGTAG, "Create Map_Geopoint table");
			db.execSQL(MAP_GEOPOINT_CREATE);
			BlackPublic.debugLog(LOGTAG, "Create Map_Address table");
			db.execSQL(MAP_ADDRESS_CREATE);
		}

		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
			BlackPublic.debugLog(LOGTAG, "Drop Map_Address table");
			db.execSQL("DROP TABLE IF EXISTS " + MAP_ADDRESS_TABLE);
			BlackPublic.debugLog(LOGTAG, "Drop Map_Geopoint table");
			db.execSQL("DROP TABLE IF EXISTS " + MAP_GEOPOINT_TABLE);
			onCreate(db);
		}

		@Override
		public synchronized void close() {
			// TODO Auto-generated method stub
			super.close();
		}
	}
}
